package oauth

import (
	"net/http"
	"net/url"
	"strings"

	"chainmaker.org/chainmaker/smarteditor/conf"
	ssoUser "chainmaker.org/chainmaker/smarteditor/oauth/sso_user"
	"chainmaker.org/chainmaker/smarteditor/session"
)

const (
	ssoCookieUserId = "user_id"
	ssoCookieToken  = "token"
)

var _ AuthServerHandler = (*SSOAuthServerHandler)(nil)

type SSOAuthServerHandler struct {
}

func (sso SSOAuthServerHandler) GetAuthServerFlag() string {
	return string(SSO)
}

func (sso SSOAuthServerHandler) LoginRedirectHandler(w http.ResponseWriter, r *http.Request, stateCode, site string) {

	oauthUrl := sso.buildOauthUrl(
		conf.Wide.SsoOAuthServer, conf.Wide.PublicServer, stateCode,
		site)

	http.Redirect(w, r, oauthUrl, http.StatusSeeOther)
}

func (sso SSOAuthServerHandler) LoginCallbackHandler(w http.ResponseWriter, r *http.Request, stateCode, site string) {

	tokenCookie, tokenCookieErr := r.Cookie(ssoCookieToken)
	if tokenCookieErr != nil || tokenCookie == nil {
		log.Warnf("LoginCallbackHandler cookie get jwttoken failed [%+v] ", tokenCookieErr)
		http.Error(w, "illegal login", http.StatusBadRequest)
		return
	}
	userIdCookie, userIdCookieErr := r.Cookie(ssoCookieUserId)
	if userIdCookieErr != nil || userIdCookie == nil {
		log.Warnf("LoginCallbackHandler cookie get userIdCookie failed [%+v] ", userIdCookieErr)
		http.Error(w, "illegal login", http.StatusBadRequest)
		return
	}
	userIdV, _ := url.QueryUnescape(userIdCookie.Value)
	user, queryErr := ssoUser.GetUserInfoByUserId(userIdV)
	if queryErr != nil {
		log.Errorf("LoginCallbackHandler GetUserInfoByUserId %s failed %s ", userIdV, queryErr.Error())
		http.Error(w, "Forbidden", http.StatusForbidden)
		return
	}
	session.LoginCallbackHandler(userIdV, user.UserName, user.HeadImg, site, w, r)
}

func (sso SSOAuthServerHandler) ThirdPartLoginHandler(w http.ResponseWriter, r *http.Request, site string) {
	http.Error(w, "unsupported", http.StatusInternalServerError)
}

func (sso SSOAuthServerHandler) buildOauthUrl(oauthServer, publicServer, stateCode, site string) string {
	var buffer strings.Builder
	buffer.WriteString("https://")
	buffer.WriteString(oauthServer)
	buffer.WriteString("/login?")
	//redirect url
	buffer.WriteString("&appUrl=")
	buffer.WriteString(url.QueryEscape(GetRedirectUrl(publicServer, sso.GetAuthServerFlag(), stateCode, site)))
	return buffer.String()
}
